/**
 * 
 */
package de.cbf.cam.dsa.model.entities.items.transfers;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.TransferData;

import de.cbf.cam.dsa.model.entities.items.Elixir;
import de.cbf.cam.dsa.model.entities.states.stateChanger.StateChangerBase;

/**
 * @author Nebelritter
 *
 */
public class ElixirTransfer extends ByteArrayTransfer implements ITransfer{
	private static final String TYPENAME = "elixirTransfer";

	private static final int TYPEID = registerType(TYPENAME);

	private static ElixirTransfer instance = new ElixirTransfer();
	
	public static ElixirTransfer getInstance() {
		return instance;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.swt.dnd.Transfer#getTypeIds()
	 */
	@Override
	protected int[] getTypeIds() {
		return new int[] { TYPEID };
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.swt.dnd.Transfer#getTypeNames()
	 */
	@Override
	protected String[] getTypeNames() {
		return new String[] { TYPENAME };		
	}	

	boolean checkItem(Object object) {
		return (object != null && object instanceof Elixir);
	}

	protected boolean validate(Object object) {
		return checkItem(object);
	}
	
	public void javaToNative(Object object, TransferData transferData) {
	    if (!checkItem(object) || !isSupportedType(transferData)) {
	    	DND.error(DND.ERROR_INVALID_DATA);
	    }
	    Elixir elixir = (Elixir) object;
	    try {
	    	// write data to a byte array and then ask super to convert to
	    	// pMedium
	    	ByteArrayOutputStream out = new ByteArrayOutputStream();
	    	DataOutputStream writeOut = new DataOutputStream(out);
	    	 
	    	writeElixir(elixir, writeOut);
	    	  
	        
	    	byte[] buffer = out.toByteArray();
	    	writeOut.close();
	    	
	    	super.javaToNative(buffer, transferData);
	    } catch (IOException e) {
	    }
	}

	public Object nativeToJava(TransferData transferData) {
		if (isSupportedType(transferData)) {
			byte[] bufferAll = (byte[]) super.nativeToJava(transferData);
  		if (bufferAll == null){
  			return null;
  		}
  		Elixir elixir = new Elixir();
  		try {
  			ByteArrayInputStream in = new ByteArrayInputStream(bufferAll);
  			DataInputStream readIn = new DataInputStream(in);
  			while (readIn.available() > 20) {
  				
  				readElixir(elixir,readIn);
  			}
  			readIn.close();
  			return elixir;
        } catch (IOException ex) {	        	
          return null;
        }        
    }
    return null;
  }
	  
	static void writeElixir(Elixir elixir,DataOutputStream writeOut) throws IOException{
		ItemTransfer.writeItem(elixir, writeOut);
		//write elixir specifics -> stateChanger
		int countOfStateChangers = elixir.getStateChangers().size(); 
		writeOut.writeInt(countOfStateChangers);
		for(int i = 0;i<countOfStateChangers;i++){
			StateChangerBase stateChanger = elixir.getStateChangers().get(i);
			TransferSubEntities.writeStateChanger(stateChanger, writeOut);
		}		  
	}
  
	static void readElixir(Elixir elixir,DataInputStream readIn) throws IOException{
		ItemTransfer.readItem(elixir, readIn);
		//read elixir specifics
		int countOfStateChangers = readIn.readInt();
		for(int i = 0;i<countOfStateChangers;i++){
			StateChangerBase stateChanger = TransferSubEntities.readStateChanger(readIn);
			elixir.addStateChanger(stateChanger);
		}
	}
	  
	@Override
	public String toString() {
		return getClass().getSimpleName();
	}
}
